package com.xyht.sca_s.student_manage_system.modules.scheduleManagement.util;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.util.TimeUtil;
import com.xyht.sca_s.student_manage_system.modules.meeting.util.AddMeetingUtil;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.AppTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.RangeTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsRecordStatusEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.myEnum.TipsTypeEnum;
import com.xyht.sca_s.student_manage_system.modules.newTips.util.NewTipsUtil;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.SmsSchedule;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.SmsScheduleNotice;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.SmsSchedulePersonRelation;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.entity.req.SmsScheduleReq;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.mapper.SmsScheduleMapper;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.mapper.SmsScheduleNoticeMapper;
import com.xyht.sca_s.student_manage_system.modules.scheduleManagement.mapper.SmsSchedulePersonRelationMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.AcceptTypeConstant.ACCEPT_TYPE_ACCEPT;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.CommonConstant.SCHEDULE_BOOLEAN_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.IsOverDayFlagConstant.IS_OVER_DAY_FALSE;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.IsOverDayFlagConstant.IS_OVER_DAY_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.PersonTypeConstant.PERSON_TYPE_CREATOR;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.PersonTypeConstant.PERSON_TYPE_PERSON;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.RepeatTypeConstant.REPEAT_TYPE_NEVER;
import static com.xyht.sca_s.student_manage_system.modules.scheduleManagement.constant.ScheduleTypeConstant.SCHEDULE_TYPE_MEETING;

@Component
public class ScheduleManagementUtil {
    @Autowired
    private SmsScheduleMapper smsScheduleMapper;
    @Autowired
    private AddMeetingUtil addMeetingUtil;
    @Autowired
    private SmsSchedulePersonRelationMapper smsSchedulePersonRelationMapper;
    @Autowired
    private SmsScheduleNoticeMapper smsScheduleNoticeMapper;
    @Autowired
    private NewTipsUtil newTipsUtil;

    public String addMeetingAndSchedule(SmsScheduleReq smsScheduleReq,
                                        Date bgDate,
                                        Date endDate,
                                        String user_id,
                                        String scheduleRepeatId) {
        SmsSchedule smsSchedule = new SmsSchedule();
        BeanUtils.copyProperties(smsScheduleReq, smsSchedule);
        smsSchedule.setScheduleBeginTime(bgDate);
        smsSchedule.setScheduleEndTime(endDate);
        smsSchedule.setScheduleRepeatId(scheduleRepeatId);
        smsSchedule.setRepeatCustomWeek(JSON.toJSONString(smsScheduleReq.getRepeatCustomWeek()));

        //是否会议
        if (smsScheduleReq.getScheduleType().equals(SCHEDULE_TYPE_MEETING)) {
            String meetingOrderID = addMeetingUtil.addMeeting(smsScheduleReq.getMeetingRoomId(),
                    smsScheduleReq.getScheduleTopic(),
                    bgDate,
                    endDate,
                    smsScheduleReq.getPersonList(),
                    user_id);
            if (meetingOrderID == null) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.SCHEDULE_MEETING_ADD_ERR));
            }
            smsSchedule.setScheduleMeetingId(meetingOrderID);
        }

        return addSingleSchedule(smsSchedule,
                smsScheduleReq.getPersonList(),
                smsScheduleReq.getNoticeList(),
                user_id);
    }

    /**
     * 添加日程（内部调用接口）
     *
     * @param meeting_id           会议id
     * @param bgDate               开始时间
     * @param endDate              结束时间
     * @param personList           参会人员集合
     * @param topic_name           主题名
     * @param user_id              创建用户
     * @param is_open              是否公开   0: 不公开  1：公开
     * @param schedule_addr        日程地址
     * @param schedule_description 日程描述
     * @param is_notice            是否发送提醒  0: 不发送  1：发送
     */
    public void addSingleSchedule(String meeting_id,
                                  String topic_name,
                                  List<String> personList,
                                  Date bgDate,
                                  Date endDate,
                                  String user_id,
                                  Integer is_open,
                                  String schedule_addr,
                                  String schedule_description,
                                  Integer is_notice) {
        if (isNullOrEmpty(meeting_id) || isNullOrEmpty(topic_name) || isNullOrEmpty(personList)
                || isNullOrEmpty(bgDate) || isNullOrEmpty(endDate) || isNullOrEmpty(user_id)
                || isNullOrEmpty(is_open) || isNullOrEmpty(schedule_addr) || isNullOrEmpty(is_notice)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        SmsSchedule smsSchedule = new SmsSchedule();
        smsSchedule.setScheduleBeginTime(bgDate);
        smsSchedule.setScheduleEndTime(endDate);
        smsSchedule.setRepeatType(REPEAT_TYPE_NEVER);
        smsSchedule.setScheduleTopic(topic_name);
        smsSchedule.setScheduleMeetingId(meeting_id);
        smsSchedule.setScheduleType(SCHEDULE_TYPE_MEETING);
        smsSchedule.setIsOpen(is_open);
        smsSchedule.setScheduleAddr(schedule_addr);
        smsSchedule.setScheduleDescription(schedule_description);

        String event_id = addSingleSchedule(smsSchedule,
                personList,
                null,
                user_id);

        if (is_notice == SCHEDULE_BOOLEAN_TRUE) {
            newTipsUtil.addNewTips(TipsTypeEnum.TIPS_TYPE_ENUM_MESSAGE,
                    user_id,
                    RangeTypeEnum.RANGE_TYPE_ENUM_PERSON,
                    personList,
                    AppTypeEnum.APP_TYPE_ENUM_SCHEDULE,
                    event_id,
                    "",
                    "你有一个新的日程待查看",
                    TipsRecordStatusEnum.TIPS_RECORD_STATUS_ENUM_MESSAGE);
        }
    }

    /**
     * 修改日程（内部调用接口）
     *
     * @param meeting_id           会议id
     * @param bgDate               开始时间
     * @param endDate              结束时间
     * @param personList           参会人员集合
     * @param topic_name           主题名
     * @param user_id              创建用户
     * @param is_open              是否公开   0: 不公开  1：公开
     * @param schedule_addr        日程地址
     * @param schedule_description 日程描述
     * @param is_notice            是否发送提醒  0: 不发送  1：发送
     */
    public void updateSingleSchedule(String meeting_id,
                                     String topic_name,
                                     List<String> personList,
                                     Date bgDate,
                                     Date endDate,
                                     String user_id,
                                     Integer is_open,
                                     String schedule_addr,
                                     String schedule_description,
                                     Integer is_notice) {
        if (isNullOrEmpty(meeting_id) || isNullOrEmpty(topic_name) || isNullOrEmpty(personList)
                || isNullOrEmpty(bgDate) || isNullOrEmpty(endDate) || isNullOrEmpty(user_id)
                || isNullOrEmpty(is_open) || isNullOrEmpty(schedule_addr) || isNullOrEmpty(is_notice)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        SmsSchedule smsSchedule = new SmsSchedule();
        smsSchedule.setScheduleBeginTime(bgDate);
        smsSchedule.setScheduleEndTime(endDate);
        smsSchedule.setRepeatType(REPEAT_TYPE_NEVER);
        smsSchedule.setScheduleTopic(topic_name);
        smsSchedule.setScheduleMeetingId(meeting_id);
        smsSchedule.setScheduleType(SCHEDULE_TYPE_MEETING);
        smsSchedule.setIsOpen(is_open);
        smsSchedule.setScheduleAddr(schedule_addr);
        smsSchedule.setScheduleDescription(schedule_description);

        List<SmsSchedule> scheduleList = smsScheduleMapper.selectList(new QueryWrapper<SmsSchedule>()
                .lambda()
                .eq(SmsSchedule::getScheduleMeetingId, meeting_id));
        if (scheduleList == null || scheduleList.size() != 1) {
            return;
        }

        deleteScheduleAndMeeting(scheduleList.get(0).getId(),null);

        String event_id = addSingleSchedule(smsSchedule,
                personList,
                null,
                user_id);

        if (is_notice == SCHEDULE_BOOLEAN_TRUE) {
            newTipsUtil.addNewTips(TipsTypeEnum.TIPS_TYPE_ENUM_MESSAGE,
                    user_id,
                    RangeTypeEnum.RANGE_TYPE_ENUM_PERSON,
                    personList,
                    AppTypeEnum.APP_TYPE_ENUM_SCHEDULE,
                    event_id,
                    "",
                    "你有一个新的日程待查看",
                    TipsRecordStatusEnum.TIPS_RECORD_STATUS_ENUM_MESSAGE);
        }
    }

    /**
     * 删除日程（内部调用接口）
     *
     * @param meeting_id           会议id
     */
    public void deleteSingleSchedule(String meeting_id) {
        List<SmsSchedule> scheduleList = smsScheduleMapper.selectList(new QueryWrapper<SmsSchedule>()
                .lambda()
                .eq(SmsSchedule::getScheduleMeetingId, meeting_id));
        if (scheduleList == null || scheduleList.size() != 1) {
            return;
        }
        deleteScheduleAndMeeting(scheduleList.get(0).getId(),null);
    }

    public String addSingleSchedule(SmsSchedule smsSchedule,
                                    List<String> personList,
                                    List<Integer> noticeList,
                                    String user_id) {
        //开始结束日期相差是否跨天
        boolean bl = TimeUtil.isDiffDay(smsSchedule.getScheduleBeginTime(), smsSchedule.getScheduleEndTime());
        smsSchedule.setIsOverDay(bl ? IS_OVER_DAY_TRUE : IS_OVER_DAY_FALSE);

        smsSchedule.setScheduleCreatorId(user_id);
        smsScheduleMapper.insert(smsSchedule);
        String schedule_id = smsSchedule.getId();
        if (isNullOrEmpty(schedule_id)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }

        //参与者列表
        if (personList != null && personList.size() > 0) {
            for (String person_id : personList) {
                if (person_id.equals(user_id)) {
                    //添加日程创建者
                    SmsSchedulePersonRelation schedulePersonRelation = new SmsSchedulePersonRelation();
                    schedulePersonRelation.setPersonType(PERSON_TYPE_CREATOR);
                    schedulePersonRelation.setScheduleId(schedule_id);
                    schedulePersonRelation.setPersonId(user_id);
                    schedulePersonRelation.setAcceptType(ACCEPT_TYPE_ACCEPT);
                    smsSchedulePersonRelationMapper.insert(schedulePersonRelation);
                    continue;
                }
                SmsSchedulePersonRelation schedulePersonRelation = new SmsSchedulePersonRelation();
                schedulePersonRelation.setPersonType(PERSON_TYPE_PERSON);
                schedulePersonRelation.setScheduleId(schedule_id);
                schedulePersonRelation.setPersonId(person_id);
                smsSchedulePersonRelationMapper.insert(schedulePersonRelation);
            }
        }

        //提醒时间点
        if (noticeList != null && noticeList.size() > 0) {
            for (Integer notice_diff_time : noticeList) {
                Date notice_time = TimeUtil.AddMinute(smsSchedule.getScheduleBeginTime(), notice_diff_time * -1);
                SmsScheduleNotice smsScheduleNotice = new SmsScheduleNotice();
                smsScheduleNotice.setScheduleId(schedule_id);
                smsScheduleNotice.setNoticeTime(notice_time);
                smsScheduleNotice.setNoticeMinute(notice_diff_time);
                smsScheduleNoticeMapper.insert(smsScheduleNotice);
            }
        }
        return smsSchedule.getId();
    }

    public void deleteScheduleAndMeeting(String schedule_id, String meeting_id) {
        //删除会议
        if (!isNullOrEmpty(meeting_id)) {
            addMeetingUtil.deleteMeeting(meeting_id);
        }
        //删除日程
        smsScheduleMapper.deleteById(schedule_id);

        //删除参会人
        smsSchedulePersonRelationMapper.delete(new QueryWrapper<SmsSchedulePersonRelation>()
                .lambda()
                .eq(SmsSchedulePersonRelation::getScheduleId, schedule_id));

        //删除提醒
        smsScheduleNoticeMapper.delete(new QueryWrapper<SmsScheduleNotice>()
                .lambda()
                .eq(SmsScheduleNotice::getScheduleId, schedule_id));
    }

}
